package org.finesys.common.security.core.config;


import org.finesys.common.security.core.support.AuthAuthenticationEntrypoint;
import org.springframework.context.annotation.Bean;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenIntrospector;
import org.springframework.security.oauth2.server.resource.web.BearerTokenResolver;
import org.springframework.security.web.SecurityFilterChain;

import cn.hutool.core.util.ArrayUtil;
import lombok.RequiredArgsConstructor;

@EnableWebSecurity
@EnableMethodSecurity
@RequiredArgsConstructor
public class AuthResourceServerConfiguration {

    private final AuthAuthenticationEntrypoint authAuthenticationEntrypoint;
    private final BearerTokenResolver bearerTokenResolver;
    private final AuthPermitAllUrlProperties authPermitAllUrlProperties;
    private final OpaqueTokenIntrospector authOpaqueTokenIntrospector;

    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {

        httpSecurity.authorizeRequests(authorizeRequest -> authorizeRequest.antMatchers(ArrayUtil.toArray(authPermitAllUrlProperties.getUrls(), String.class))
                        .permitAll()
                        .anyRequest()
                        .authenticated())
                .oauth2ResourceServer(oauth2 -> oauth2.opaqueToken(token -> token.introspector(authOpaqueTokenIntrospector))
                        .authenticationEntryPoint(authAuthenticationEntrypoint)
                        .bearerTokenResolver(bearerTokenResolver))
                .headers().frameOptions().disable()
                .and()
                .csrf().disable();
        return httpSecurity.build();
    }
}
